package com.chinaunicom.emergency.action;

import com.chinaunicom.emergency.annotation.Permission;
import com.chinaunicom.emergency.exception.CheckException;
import com.chinaunicom.emergency.model.Attachment;
import com.chinaunicom.emergency.repository.AttachmentRepository;
import com.chinaunicom.emergency.util.*;
import io.minio.ObjectStat;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.Date;

@RestController
@Log4j2
@Api(tags = {"获取文件、附件对象接口"})
public class DownloadFileAction extends BaseAction {

    @Autowired
    private AttachmentRepository attachmentRepository;

    @ApiOperation("文件展示或下载")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "need-download", value = "展示为空,下载为1", required = true, dataType = "String", paramType = "header")
    })
    @GetMapping(value = "/api/show/file")
    public Object downloadFileContent(HttpServletRequest request,
                                    HttpServletResponse response,
                                    @RequestParam(required = false) String path,
                                    @RequestParam(required = false) String id) throws CheckException {
//        InputStream in = null;
//        OutputStream os = null;
        Assert.isBlank("path或id二选一", path, id);
        try {
            Attachment attachment;
            if (StringUtils.isNotBlank(id)) {
                attachment = attachmentRepository.findByPidAndIsSoftDel(id,0);
            } else {
                attachment = attachmentRepository.getAttachmentByFileUrl(path);
            }
            Assert.isNull(attachment, "附件不存在！");
            path = attachment.getFileUrl();
            boolean isDownload = false;
//            String fileName = java.net.URLEncoder.encode(attachment.getFileName(), "UTF-8");
            if (request.getHeader("need-download") != null && request.getHeader("need-download").equals("1")) {
//                response.setHeader("content-disposition", "attachment; filename=" + new String(fileName.getBytes(), "utf-8"));
                isDownload = true;
            } else if (request.getParameter("need-download") != null && request.getParameter("need-download").equals("1")) {
//                response.setHeader("content-disposition", "attachment; filename=" + new String(fileName.getBytes(), "utf-8"));
                isDownload = true;
            }
            String[] objs = path.split(":");
            ObjectStat objectStat = MinioUtil.statObject(objs[0], objs[1]);
            //当有外部文件链接时，重定向
            if (StringUtils.isNotBlank(attachment.getManulUrl())) {
                log.info("查看外部文件链接，重定向：" + attachment.getManulUrl());
                response.sendRedirect(attachment.getManulUrl());
                return success();
            }
            if (!isDownload) {
                String resourceUrl = MinioUtil.getObjUrl(objs[0], objs[1]);
                String minioProxyUrl = ConfigUtil.get("system.minio.proxy.url");
                if (StringUtils.isNotBlank(minioProxyUrl)) {
                    String minioUrl = ConfigUtil.get("system.minio.urls");
                    resourceUrl = resourceUrl.replace(minioUrl, minioProxyUrl);
                }
                log.info("查看文件，重定向：" + resourceUrl);
                response.sendRedirect(resourceUrl);
                return success();
            }else{
                String resourceUrl = MinioUtil.getDownloadObjUrl(objs[0], objs[1],"attachment; filename=" + attachment.getFileName());
                String minioProxyUrl = ConfigUtil.get("system.minio.proxy.url");
                if (StringUtils.isNotBlank(minioProxyUrl)) {
                    String minioUrl = ConfigUtil.get("system.minio.urls");
                    resourceUrl = resourceUrl.replace(minioUrl, minioProxyUrl);
                }
                log.info("下载文件，重定向：" + resourceUrl);
                response.sendRedirect(resourceUrl);
                return success();
            }
//            response.setHeader("Access-Control-Allow-Origin", "*");
//            //关闭压缩，否则content-length不正常
//            response.setHeader("Accept-Encoding", "identity");
//            long contentLenght = 0;
//            if (objectStat != null) {
//                contentLenght = objectStat.length();
//            }
//            response.setContentType(objectStat.contentType());
//            response.setContentLengthLong(contentLenght);
//            byte[] bytes = new byte[4096];
//            int res;
//            in = MinioUtil.get(objs[0], objs[1]);
//            long size = 0;
//            os = response.getOutputStream();
//            while ((res = in.read(bytes)) != -1) {
//                size = size + res;
//                os.write(bytes, 0, res);
//            }
//            os.flush();
        } catch (Exception e) {
            log.error("获取文件失败", e);
//            try {
//                os = response.getOutputStream();
//                os.write(new byte[0]);
//                os.flush();
//            } catch (IOException e1) {
//                e1.printStackTrace();
//            }
            return error("获取文件失败:"+ e.getMessage());
        }
//       finally {
//            if (os != null) {
//                try {
//                    os.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//            if (in != null) {
//                try {
//                    in.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
    }

    @ApiOperation("缩略图")
    @GetMapping(value = "/api/show/image/base64")
    public Object showImageBase64(@RequestParam(required = false) String path,
                                  @RequestParam(required = false) String id) throws CheckException {
        Assert.isBlank("path或id二选一", path, id);
        try {
            if (StringUtils.isNotBlank(id)) {
                Attachment attachment = attachmentRepository.getOne(id);
                path = attachment.getFileUrl();
            }
            String[] objs = path.split(":");
            InputStream in = MinioUtil.get(objs[0], objs[1]);

            String base = InputStreamToBase64.getBase64FromInputStream(in);
            return success(base);
        } catch (Exception e) {
            log.error("图片处理错误", e);
            return error("图片处理错误");
        }
    }


    @ApiOperation("获取文件信息，传入附件ID")
    @GetMapping(value = "/api/show/attInfo")
    public Object showAttaInfo(@RequestParam String id) {
        return attachmentRepository.findByPidAndIsSoftDel(id,0);
    }

    @ApiOperation("删除附件")
//    @Permission("delete:attInfo:file")
    @DeleteMapping(value = "/api/delete/attInfo")
    public Object deleteAtta(@RequestParam String id) throws CheckException {
        Attachment attachment = attachmentRepository.findByPidAndIsSoftDel(id,0);
        Assert.isNull(attachment, "附件不存在！");
        String[] fileUrl = attachment.getFileUrl().split(":");
        MinioUtil.delete(fileUrl[0],fileUrl[1]);

        attachment.setIsSoftDel(1);
        attachment.setDeleteBy(getCurrUserId());
        attachment.setDeleteTime(new Date());
        attachmentRepository.save(attachment);
        return success();
    }

    @ApiOperation("修改附件信息")
    @PutMapping(value = "/api/update/attInfo")
    public Object updateAtta(@RequestBody Attachment attachment) throws CheckException {
        Assert.isBlank(attachment.getPid(), "附件id不能为空");
        Attachment attachmentDb = attachmentRepository.findByPidAndIsSoftDel(attachment.getPid(), 0);
        Assert.isNull(attachmentDb, "附件不存在");
        UpdateUtil.copyNullProperties(attachmentDb, attachment);
        attachmentRepository.save(attachment);
        return success();
    }

}

